package com.samehope.ar.service.impl;

import com.samehope.ar.constant.DelFlagEnum;
import com.samehope.ar.dto.PatrolPointCountParam;
import com.samehope.ar.dto.PointAddParam;
import com.samehope.ar.dto.PointGroupAddParam;
import com.samehope.ar.dto.PointUpdateParam;
import com.samehope.ar.entity.PatrolPoint;
import com.samehope.ar.entity.PatrolPointDetail;
import com.samehope.ar.entity.PatrolPointGroup;
import com.samehope.ar.mapper.PatrolPointMapper;
import com.samehope.ar.service.IPatrolPointDetailService;
import com.samehope.ar.service.IPatrolPointGroupService;
import com.samehope.ar.service.IPatrolPointService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.samehope.ar.util.SessionUtil;
import com.samehope.ar.util.TreeUtils;
import com.samehope.ar.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 巡检点 服务实现类
 * </p>
 *
 * @author Zhang Luo
 * @since 2019-12-23
 */
@Service
public class PatrolPointServiceImpl extends ServiceImpl<PatrolPointMapper, PatrolPoint> implements IPatrolPointService {

    @Autowired
    private IPatrolPointDetailService pointDetailService;

    @Autowired
    private IPatrolPointGroupService pointGroupService;

    /**
     * 获取巡检点树结构
     * @param condition
     * @return
     */
    @Override
    public List<TreeDataVO> getPointTree(String condition) {
        List<TreeDataVO> tree = this.baseMapper.getTreeByProjectAndCondition(SessionUtil.getProjectId(), condition);
        TreeUtils.setLevel(tree, 1);
        TreeUtils.setId(tree);
        return tree;
    }

    /**
     * 获取巡检点明细
     * @param pointId
     * @return
     */
    @Override
    public PointDetailVO detail(Long pointId) {
        return this.baseMapper.getDetailByProjectAndPoint(SessionUtil.getProjectId(), pointId);
    }

    /**
     * 删除巡检点
     * @param pointId
     */
    @Override
    public void deletePoint(Long pointId) {
        PatrolPoint patrolPoint = this.baseMapper.findByProjectAndPoint(SessionUtil.getProjectId(), pointId);

        if (patrolPoint == null) {
            throw new IllegalArgumentException("巡检点不存在");
        }

        patrolPoint.setDelFlag(DelFlagEnum.DELETED.getCode());
        patrolPoint.setUpdateBy(SessionUtil.getUserId());
        patrolPoint.setUpdateDate(LocalDateTime.now());

        this.updateById(patrolPoint);
    }

    /**
     * 新增巡检点
     * @param param
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long add(PointAddParam param) {

        Long pointGroupId = this.checkAndGetPointGroup(param.getPointGroupId(), param.getPointGroupName());

        PatrolPoint patrolPoint = this.baseMapper
                .getPointByProjectAndPointName(SessionUtil.getProjectId(), param.getPointName());

        if (patrolPoint != null) {
            throw new IllegalArgumentException("点位名称已存在");
        }

        patrolPoint = new PatrolPoint();
        patrolPoint.setCompanyId(SessionUtil.getCompanyId());
        patrolPoint.setProjectId(SessionUtil.getProjectId());
        patrolPoint.setPointName(param.getPointName());
        patrolPoint.setPointCode(param.getPointCode());
        patrolPoint.setPointAddress(param.getPointAddress());
        patrolPoint.setCoordinate(param.getCoordinate());
        patrolPoint.setPatrolPointGroupId(pointGroupId);
        patrolPoint.setIsMustCheck(param.getIsMustCheck());
        patrolPoint.setErrorGrade(param.getErrorGrade());
        patrolPoint.setCreateBy(SessionUtil.getUserId());

        this.save(patrolPoint);

        List<PatrolPointDetail> details = new ArrayList<>();
        List<Long> itemIds = param.getItemIds();
        for (int i = 0; i < itemIds.size(); i++) {
            PatrolPointDetail patrolPointDetail = new PatrolPointDetail();
            patrolPointDetail.setPatrolPointId(patrolPoint.getId());
            patrolPointDetail.setPatrolItemId(itemIds.get(i));
            patrolPointDetail.setCreateBy(SessionUtil.getUserId());
            details.add(patrolPointDetail);
        }

        pointDetailService.saveBatch(details);
        return patrolPoint.getId();
    }

    /**
     * 更新巡检点
     * @param param
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void update(PointUpdateParam param) {

        Long pointGroupId = this.checkAndGetPointGroup(param.getPointGroupId(), param.getPointGroupName());

        final LocalDateTime now = LocalDateTime.now();

        PatrolPoint src = this.baseMapper.findByProjectAndPoint(SessionUtil.getProjectId(), param.getPointId());

        if (src == null) {
            throw new IllegalArgumentException("点位不存在");
        }

        PatrolPoint patrolPoint = this.baseMapper
                .getPointByProjectAndPointName(SessionUtil.getProjectId(), param.getPointName());

        if (patrolPoint != null && !src.getId().equals(patrolPoint.getId())) {
            throw new IllegalArgumentException("点位名称已存在");
        }

        src.setPointName(param.getPointName());
        src.setPointCode(param.getPointCode());
        src.setPointAddress(param.getPointAddress());
        src.setCoordinate(param.getCoordinate());
        src.setPatrolPointGroupId(pointGroupId);
        src.setIsMustCheck(param.getIsMustCheck());
        src.setErrorGrade(param.getErrorGrade());
        src.setUpdateBy(SessionUtil.getUserId());
        src.setUpdateDate(now);

        this.updateById(src);

        // 移除旧的巡检项
        List<PatrolPointDetail> details = pointDetailService.findDetailsByPoint(param.getPointId());
        details.forEach(e -> {
            e.setDelFlag(DelFlagEnum.DELETED.getCode());
            e.setUpdateBy(SessionUtil.getUserId());
            e.setUpdateDate(now);
        });
        pointDetailService.updateBatchById(details);

        details = new ArrayList<>();
        List<Long> itemIds = param.getItemIds();
        for (int i = 0; i < itemIds.size(); i++) {
            PatrolPointDetail patrolPointDetail = new PatrolPointDetail();
            patrolPointDetail.setPatrolPointId(src.getId());
            patrolPointDetail.setPatrolItemId(itemIds.get(i));
            patrolPointDetail.setCreateBy(SessionUtil.getUserId());
            patrolPointDetail.setCreateDate(now);
            details.add(patrolPointDetail);
        }

        pointDetailService.saveBatch(details);

    }

    /**
     * 检查和获取点位分组ID
     * @param pointGroupId
     * @param pointGroupName
     * @return
     */
    private Long checkAndGetPointGroup(Long pointGroupId, String pointGroupName) {

        if (pointGroupName != null) {
            PatrolPointGroup pointGroup = pointGroupService.findGroupByGroupName(pointGroupName);
            if (pointGroup == null) {
                PointGroupAddParam pointAddParam = new PointGroupAddParam();
                pointAddParam.setName(pointGroupName);
                pointGroupId = pointGroupService.add(pointAddParam);
            } else {
                pointGroupId = pointGroup.getId();
            }
        }

        return pointGroupId;
    }

    @Override
    public PatrolPointCountVO countByPoint(PatrolPointCountParam param){
        return this.baseMapper.countByPoint(param.getPatrolPointId(), param.getStartTime(), param.getEndTime());
    }

    @Override
    public ChartArrayDataVo countByProblemType(PatrolPointCountParam param){
        List<ChartDataVo> list = this.baseMapper.countByProblemType(param.getPatrolPointId(), param.getStartTime(), param.getEndTime());
        ChartArrayDataVo chartArrayDataVo = new ChartArrayDataVo();
        List<String> name = new ArrayList<String>();
        List<Integer> value = new ArrayList<Integer>();
        if(list != null){
            for(ChartDataVo data:list){
                name.add(data.getName());
                value.add(data.getValue());
            }
        }
        chartArrayDataVo.setName(name);
        chartArrayDataVo.setValue(value);
        return chartArrayDataVo;
    }

    @Override
    public List<ChartDataVo> countByProblemItem(PatrolPointCountParam param){
        return this.baseMapper.countByProblemItem(param.getPatrolPointId(), param.getStartTime(), param.getEndTime());
    }

    /**
     * 获取巡检点树结构, 没有点位的分类不显示
     * @return
     */
    @Override
    public List<TreeDataVO> getPointTreeWithFullNode() {
        List<TreeDataVO> tree = this.baseMapper.getTreeWithFullNodeByProject(SessionUtil.getProjectId());
        TreeUtils.setLevel(tree, 1);
        TreeUtils.setId(tree);
        return tree;
    }

}
